package main

import (
	"flag"
	"fmt"
	"os/exec"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/gookit/color"
)

var ipSucess []string

func checkIpInfo(ips string) bool {
	addr := strings.Trim(ips, " ")
	// regStr := `^(([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$`
	regStr := `^(([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){2}$`
	if match, _ := regexp.MatchString(regStr, addr); match {
		return true
	}
	return false
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	var b string
	// fmt.Printf("请输入网段(如10.1.203.): ")
	// fmt.Scanln(&b)

	flag.StringVar(&b, "net", "", "请指定网段（网段后注意加点），如 cping -net 10.1.203.")
	// var b = flag.String("net", "network", "for example 10.1.203.")
	flag.Parse()
	// fmt.Printf("网段为%s:", b)

	if checkIpInfo(b) {

		start := time.Now()
		c := make(chan string)
		for i := 0; i < 255; i++ {
			target := fn0(b, i)
			// fmt.Println(target)
			// go pingHost(target, c)
			go runCmd(target, c)

		}

		for i := 0; i < 255; i++ {
			_ = <-c

		}

		conDisplay(ipSucess)
		end := time.Now()
		fmt.Printf("\n\n%s网段在线数%v台\telapsed:%s", b, len(ipSucess), end.Sub(start))

	} else {
		// fmt.Println("输入信息不正确，请重新输入!")
		flag.Usage()
	}
}

func fn0(b string, i int) string {
	target := b + strconv.Itoa(i)
	return target
}

func in(target string, str_array []string) bool {
	for _, element := range str_array {
		if target == element {
			return true
		}
	}
	return false
}

func conDisplay(ips []string) {
	fmt.Printf("cPing Ver:0.1 Date:20201218\n")
	fmt.Printf("Ping Results:\n\n")
	n := 16

	for i := 0; i <= 254; i++ {

		target := strconv.Itoa(i)
		// result := in(target, ips)
		if in(target, ips) == true {
			color.Green.Printf("  %3.d", i)
		} else {
			color.Gray.Printf("  %3.d", i)

		}

		if (i+1)%n == 0 {
			fmt.Printf("\n")

		}

	}

}

func runCmd(v string, c chan string) {

	cmdline := "ping -n 2 -w 5" + " " + v
	cmd := exec.Command("cmd", "/c", cmdline)
	// cmd.Stdout = os.Stdout
	if err := cmd.Run(); err != nil {

	} else {
		// fmt.Printf("%s is over\n", v)
		v2 := strings.Split(v, ".")
		ipSucess = append(ipSucess, v2[len(v2)-1])
	}

	c <- v
}
